package fr.mywiki.business.entry.meta.datatype;

import java.text.ParseException;
import java.util.Date;
import java.util.Locale;

import org.jdom.Attribute;
import org.jdom.Element;

import fr.mywiki.business.entry.meta.DataType;
import fr.mywiki.business.resources.ResourceManager;
import fr.mywiki.business.utils.DateUtils;

public class DateProperty implements DataType {
  public static final String TYPE_NAME = "date";
  
  public static final String TYPE_BUNDLE_KEY = "model.type.date.display";
  public static final String TYPE_BUNDLE_KEY_MORE = "model.type.date.display.morethan";
  public static final String TYPE_BUNDLE_KEY_LESS = "model.type.date.display.lessthan";
  public static final String TYPE_BUNDLE_KEY_BETWEEN = "model.type.date.display.between";
  
  /* The errors */
  public static final String INVALID_TYPE = "model.validation.date.badtype";
  public static final String INVALID_DATE_MIN = "model.validation.date.tooearly";
  public static final String INVALID_DATE_MAX = "model.validation.date.toolate";
  
  /* Xml attributes names */
  public static final String MIN_DATE = "min";
  public static final String MAX_DATE = "max";
  
  /** The eventual bottom limit for the date */ 
  private Date minDate;
  
  /** The eventual upper limit for the date */
  private Date maxDate;
  
  public String checkValue(Object value) {
  	Date date;
		try {
			date = (Date) getValue(value.toString());
		} catch (ParseException e) {
			return INVALID_TYPE;
		}
  	
  	if(minDate!=null && date.before(minDate))
  		return INVALID_DATE_MIN;
  	
  	if(maxDate!=null && date.before(maxDate))
  		return INVALID_DATE_MAX;
  	
		return null;
	}
  
  public Object getValue(String strVal) throws ParseException {
		return DateUtils.parseDate(strVal);
	}
  
  public String getTypeName() {
   return TYPE_NAME;
  }
  
  /**
   * Constructor with bounds.
   * 
   * @param minDate
   *          bottom limit for the date
   * @param maxDate
   *          upper limit for the date
   */
  public DateProperty(Date minDate, Date maxDate) {
    this.minDate = minDate;
    this.maxDate = maxDate;
  }
  
  public DateProperty(){
    this(null,null);
  }

  public Date getMaxDate() {
    return maxDate;
  }

  public void setMaxDate(Date maxDate) {
    this.maxDate = maxDate;
  }

  public Date getMinDate() {
    return minDate;
  }

  public void setMinDate(Date minDate) {
    this.minDate = minDate;
  }
  
  public String getDisplayKey() {
  	return TYPE_BUNDLE_KEY;
  }

	public String describe(Locale locale) {
		StringBuffer buffer = new StringBuffer();
		
		buffer.append(ResourceManager.getMessage(TYPE_BUNDLE_KEY, locale));
		if (minDate != null) {
			if (maxDate != null) {
				// Between ...
				buffer.append(" "+ResourceManager.getMessage(TYPE_BUNDLE_KEY_BETWEEN,
						locale, new String[] { DateUtils.formatDate(minDate),
								DateUtils.formatDate(maxDate) }));
			} else {
				// More than ...
				buffer.append(" "+ResourceManager.getMessage(TYPE_BUNDLE_KEY_MORE, locale,
						new String[] { DateUtils.formatDate(minDate) }));
			}
		} else if (maxDate != null) {
			// Less than ...
			buffer.append(" "+ResourceManager.getMessage(TYPE_BUNDLE_KEY_LESS, locale,
					new String[] { DateUtils.formatDate(maxDate) }));
		}
		
		return buffer.toString();
	}

	public void describeXml(Element elt) {
		if (getMinDate() != null)
			elt.addAttribute(MIN_DATE, DateUtils.formatDate(getMinDate()));
		if (getMaxDate() != null)
			elt.addAttribute(MAX_DATE, DateUtils.formatDate(getMaxDate()));
	}

	public void fillFromXml(Element elt) {
		try {
			Attribute attr = elt.getAttribute(MIN_DATE);
			if (attr != null)
				setMinDate(DateUtils.parseDate(attr.getValue()));

			attr = elt.getAttribute(MAX_DATE);
			if (attr != null)
				setMaxDate(DateUtils.parseDate(attr.getValue()));
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
}
